package com.lxd.sunso.product.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.lxd.sunso.common.utils.CRC8Utils;
import com.lxd.sunso.common.utils.DateUnit;
import com.lxd.sunso.product.components.ConversionUtil;
import com.lxd.sunso.product.components.SnowFlakeUtil;
import com.lxd.sunso.product.entity.*;
import com.lxd.sunso.product.netty.domain.ApnVo;
import com.lxd.sunso.product.netty.domain.Device;
import com.lxd.sunso.product.netty.domain.InfoProtocol;
import com.lxd.sunso.product.netty.domain.SocketVo;
import com.lxd.sunso.product.netty.util.CacheUtil;
import com.lxd.sunso.product.netty.util.MsgUtil;
import com.lxd.sunso.product.service.*;
import com.lxd.sunso.product.vo.MachineData;
import io.netty.buffer.Unpooled;
import io.netty.channel.*;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.util.*;

import static com.lxd.sunso.product.netty.util.CacheUtil.*;

@Service("nettyService")
public class NettyServiceImpl implements NettyService {
    private static final Logger logger = LoggerFactory.getLogger("newLogger");

    @Autowired
    private MachineService machineService;

    @Autowired
    private DatatemplateService datatemplateService;

    @Autowired
    private ControlrealtimeService controlrealtimeService;

    @Autowired
    private HistroydataService histroydataService;

    @Autowired
    private AlarmregisterService alarmregisterService;

    @Autowired
    private AlarmhisdataService alarmhisdataService;

    @Autowired
    private MachinekindService machinekindService;

    @Override
    public void sendMsgToMachine(MachineData machineData) {
        List<String> machineList = machineData.getMachineName();
        if (machineData.getValue() == null) {
            return;
        }
        if (machineList != null && machineList.size() > 0) {
            for (String machineName : machineList) {
                MachineEntity machineEntity = machineService.getOne(new QueryWrapper<MachineEntity>().eq("MachineName", machineName));
                //获取到该模板的所有数据点
                List<DatatemplateEntity> entityList = datatemplateService.list(new QueryWrapper<DatatemplateEntity>().eq("TemplateID", machineEntity.getTemplateid()));
                DatatemplateEntity datatemplateEntity = null;
                for (DatatemplateEntity entity : entityList) {
                    //寻找对应寄存器的数据点
                    if (entity.getRegisteraddress().equals(machineData.getAddress())) {
                        datatemplateEntity = entity;
                    }
                }
                long datatypeid = datatemplateEntity.getDatatypeid();
                String sort = datatemplateEntity.getSrot();
                //代表解析后的数据
                String parsedata = null;
                switch (String.valueOf(datatypeid)) {
                    case "1":
                        parsedata = ConversionUtil.booleanToHex(machineData.getValue(), sort);
                        break;
                    case "2":
                        parsedata = ConversionUtil.unsignedDecToHex(machineData.getValue(), sort);
                        break;
                    case "3":
                        parsedata = ConversionUtil.unsignedDecToHex10(machineData.getValue(), sort);
                        break;
                    case "4":
                        parsedata = ConversionUtil.unsignedDecToHex100(machineData.getValue(), sort);
                        break;
                    case "5":
                        parsedata = ConversionUtil.signedDecToHex(machineData.getValue(), sort);
                        break;
                    case "6":
                        parsedata = ConversionUtil.signedDecToHex10(machineData.getValue(), sort);
                        break;
                    case "7":
                        parsedata = ConversionUtil.signedDecToHex100(machineData.getValue(), sort);
                        break;
                    case "8":
                        parsedata = ConversionUtil.unsignedDecToHex32(machineData.getValue(), sort);
                        break;
                    case "9":
                        parsedata = ConversionUtil.signedDecToHex32(machineData.getValue(), sort);
                        break;
                    case "10":
                        parsedata = ConversionUtil.floatToHex(machineData.getValue(), sort);
                        break;
                    case "11":
                        String s = ConversionUtil.StringToHex(machineData.getValue(), sort);
                        String registernum = datatemplateEntity.getRegisternum();
                        int dataLength = Integer.valueOf(registernum) * 4;
                        parsedata = StringUtils.leftPad(s, dataLength, '0');
                        break;
                }
                //此时数据已经转为了16进制
                //接下来我们对数据进行拼接
                String head = "00000200";//头部
                //数据长度
                String registernum = datatemplateEntity.getRegisternum();
                int num = Integer.valueOf(registernum) * 2 + 1 + 1;//寄存器数量+寄存器起始地址+设定的值
                //转为16进制
                String hex = ConversionUtil.DecToHex(num);
                //System.out.println(hex);
                StringBuilder data = new StringBuilder();
                //TODO 校验码以及字符串的长度处理
                String slength = ConversionUtil.DecToHex(Integer.valueOf(registernum));//处理后的数据长度格式

                //校验的数据
                StringBuilder vertifyData = new StringBuilder();
                vertifyData.append(head).append(hex).append(machineData.getAddress()).append(slength).append(parsedata);
                String crc8 = CRC8Utils.CRC8_REMAXIM(vertifyData.toString());
                if (crc8.length() < 2) {
                    crc8 = StringUtils.leftPad(crc8, 2, '0');
                }
                String subcrc8 = crc8.substring(crc8.length() - 2, crc8.length());
                //截取校验值的后两位
                data.append("5b").append(head).append(hex).append(machineData.getAddress()).append(slength).append(parsedata).append(subcrc8).append("5d");
                String message = data.toString();
                byte[] bytes = ConversionUtil.hexStringToByteArray(message);

                Collection<Device> deviceInfos = CacheUtil.deviceGroup.values();
                for (Device device : deviceInfos) {
                    if (device.getMachineName().equals(machineName)) {
                        //获取对应的通道
                        Channel channel = CacheUtil.cacheClientChannel.get(device.getChannelId());
                        //传送数据
                        ChannelFuture channelFuture = channel.writeAndFlush(Unpooled.copiedBuffer(bytes));
                        //TODO 添加监听写数据到数据库
                        //System.out.println(datatemplateEntity);
                        DatatemplateEntity finalDatatemplateEntity = datatemplateEntity;
                        channelFuture.addListener((ChannelFutureListener) future -> {
                            //如果写出成功
                            if (future.isSuccess()) {
                                ControlrealtimeEntity entity = new ControlrealtimeEntity();
                                entity.setOntime(DateUnit.dateFormat(new Date()));
                                entity.setRealtimevalue(machineData.getValue());
                                controlrealtimeService.update(entity, new QueryWrapper<ControlrealtimeEntity>().eq("MachineId", machineEntity.getId()).eq("DataTemplateId", finalDatatemplateEntity.getId()));
                            }
                        });
                    }
                }
            }
        }
    }

    @Override
    public void call(String machineName) {
        Collection<Device> deviceInfos = CacheUtil.deviceGroup.values();
        for (Device device : deviceInfos) {
            if (device.getMachineName().equals(machineName)) {
                //获取对应的通道
                Channel channel = CacheUtil.cacheClientChannel.get(device.getChannelId());
                String message = "5b000008000200ff1e5d";
                byte[] bytes = ConversionUtil.hexStringToByteArray(message);

                //传送数据
                channel.writeAndFlush(Unpooled.copiedBuffer(bytes));
            }
        }
    }

    @Override
    public void restart(String machineName) {
        Collection<Device> deviceInfos = CacheUtil.deviceGroup.values();
        for (Device device : deviceInfos) {
            if (device.getMachineName().equals(machineName)) {
                //获取对应的通道
                Channel channel = CacheUtil.cacheClientChannel.get(device.getChannelId());
                String message = "5b000099000200ff025d";
                byte[] bytes = ConversionUtil.hexStringToByteArray(message);

                //传送数据
                ChannelFuture channelFuture = channel.writeAndFlush(Unpooled.copiedBuffer(bytes));
            /*    channelFuture.addListener((ChannelFutureListener) future -> {
                    //如果写出成功
                    if (future.isSuccess()) {

                    }
                });*/
            }
        }
    }

    //下发查询socket信息
    @Override
    public SocketVo getSocket(String machineName) {
        Collection<Device> deviceInfos = CacheUtil.deviceGroup.values();
        Device deviceEntity = null;
        for (Device device : deviceInfos) {
            if (device.getMachineName().equals(machineName)) {
                deviceEntity = device;
                Channel channel = CacheUtil.cacheClientChannel.get(device.getChannelId());
                String message = "5b000006000200ffa85d";
                byte[] bytes = ConversionUtil.hexStringToByteArray(message);
                channel.writeAndFlush(Unpooled.copiedBuffer(bytes));
            }
        }

        if (deviceEntity == null) {
            return null;
        }
        String channelId = deviceEntity.getChannelId();
        SocketVo socketVo = null;
        long start = System.currentTimeMillis();
        while (socketVo == null) {
            long end = System.currentTimeMillis();
            try {
                Thread.sleep(250);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            if (end - start > 5000) {
                break;
            }
            socketVo = socketGroup.get(channelId);
            socketGroup.remove(channelId);
        }
        return socketVo;
    }

    //下发数据设置socket的值
    @Override
    public void setSocket(String machineName, SocketVo socketVo) {
        Collection<Device> deviceInfos = CacheUtil.deviceGroup.values();
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append(socketVo.getAggrement() + "," + socketVo.getIp() + "," + socketVo.getPort());
        String data = ConversionUtil.StringToHex(stringBuilder.toString());
        int length = data.length();
        //数据长度
        String datalength = ConversionUtil.DecToHex(length / 2);
        //进行CRC8校验
        StringBuilder builder = new StringBuilder();
        String crcString = builder.append("00000600").append(datalength).append(data).toString();

        String crc8 = CRC8Utils.CRC8_REMAXIM(crcString);

        StringBuilder builder1 = new StringBuilder();
        String message = builder1.append("5b00000600").append(datalength).append(data).append(crc8).append("5d").toString();
        byte[] bytes = ConversionUtil.hexStringToByteArray(message);


        for (Device device : deviceInfos) {
            if (device.getMachineName().equals(machineName)) {
                Channel channel = CacheUtil.cacheClientChannel.get(device.getChannelId());
                channel.writeAndFlush(Unpooled.copiedBuffer(bytes));
            }
        }
    }

    @Override
    public ApnVo getApn(String machineName) {
        Collection<Device> deviceInfos = CacheUtil.deviceGroup.values();
        Device deviceEntity = null;
        for (Device device : deviceInfos) {
            if (device.getMachineName().equals(machineName)) {
                deviceEntity = device;
                Channel channel = CacheUtil.cacheClientChannel.get(device.getChannelId());
                String message = "5b000007000200ff7b5d";
                byte[] bytes = ConversionUtil.hexStringToByteArray(message);
                channel.writeAndFlush(Unpooled.copiedBuffer(bytes));
            }
        }

        if (deviceEntity == null) {
            return null;
        }

        String channelId = deviceEntity.getChannelId();
        ApnVo apnVo = null;
        long start = System.currentTimeMillis();
        while (apnVo == null) {
            long end = System.currentTimeMillis();
            try {
                Thread.sleep(250);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            if (end - start > 5000) {
                break;
            }
            apnVo = apnGroup.get(channelId);
            socketGroup.remove(channelId);
        }
        return apnVo;
    }

    @Override
    public void setApn(String machineName, ApnVo apnVo) {
        Collection<Device> deviceInfos = CacheUtil.deviceGroup.values();
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append(apnVo.getCode() + "," + apnVo.getUsername() + "," + apnVo.getPassword());
        String data = ConversionUtil.StringToHex(stringBuilder.toString());
        int length = data.length();
        //数据长度
        String datalength = ConversionUtil.DecToHex(length / 2);
        //进行CRC8校验
        StringBuilder builder = new StringBuilder();
        String crcString = builder.append("00000700").append(datalength).append(data).toString();

        String crc8 = CRC8Utils.CRC8_REMAXIM(crcString);
        //对crc8进行补位
        StringBuilder builder1 = new StringBuilder();
        String message = builder1.append("5b00000700").append(datalength).append(data).append(crc8).append("5d").toString();
        byte[] bytes = ConversionUtil.hexStringToByteArray(message);
        //byte[] bytes = HexUtils.fromHexString(message);

        for (Device device : deviceInfos) {
            if (device.getMachineName().equals(machineName)) {
                Channel channel = CacheUtil.cacheClientChannel.get(device.getChannelId());
                channel.writeAndFlush(Unpooled.copiedBuffer(bytes));
            }
        }
    }

    //对下位机上传的数据进行处理
    @Override
    public void parseDataFromLow(String data, ChannelHandlerContext ctx) {
        //System.out.println(data);
        //校验CRC8是否正确
        String vertifyStr = data.substring(2, data.length() - 4);
        String crc8Str = CRC8Utils.CRC8_REMAXIM(vertifyStr);
        if (!crc8Str.equals(data.substring(data.length() - 4, data.length() - 2))) {
            return;
        }

        //如果满足这个条件的话说明是下位机请求登录的情况
        String choose = data.substring(2, 10);

        switch (choose) {
            case "01000000":
                //登录处理
                signIn(data, ctx);
                break;
            case "01000100":
                //下位机对上位机传输实时数据
                reportData(data, ctx);
                break;
            case "01000600":
                //存储socket信息在缓存中
                cacheSocket(data, ctx);
                break;
            case "01000700":
                //存储apn信息在缓存中
                cacheApn(data, ctx);
                break;
            case "010000fc":
                //设备返回当前版本号
                parseVersion(data, ctx);
                break;
            case "010000fd":
                //设备响应更新命令;
                parseStatus(data, ctx);
                break;
            //设备发送程序更新握手请求
            case "010000fe":
                //响应程序大小以及程序总包数
                responseSum(data, ctx);
                break;
            //设备请求具体包序号的程序包
            case "010000ff":
                //响应具体的程序包给设备
                sendData(data, ctx);
                break;
        }
    }

    public void testDataFromLow(String data, ChannelHandlerContext ctx) {
        // System.out.println(data);
        Channel channel = ctx.channel();
        String message = "5b000099000200ff025d";
        byte[] bytes = ConversionUtil.hexStringToByteArray(message);
        //传送数据
        ChannelFuture channelFuture = channel.writeAndFlush(Unpooled.copiedBuffer(bytes));
    }

    //设备登录
    public void signIn(String data, ChannelHandlerContext ctx) {
        //获取设备的名称
        String machineName = ConversionUtil.HexToName(data);
        MachineEntity entity = machineService.getOne(new QueryWrapper<MachineEntity>().eq("MachineName", machineName));
        //System.out.println(entity);
        if (entity == null) {
            return;
        }
        //说明设备是在数据库中存在，将设备信息加入到设备组中。
        addMachineToGroup(ctx, machineName);
        String message = "5b00000000000131";
        byte[] bytes = ConversionUtil.hexStringToByteArray(message);
        ctx.writeAndFlush(Unpooled.copiedBuffer(bytes));
        //修改设备的在线状态
        entity.setIsonline("1");
        machineService.updateById(entity);
        //打印日志
        logger.info("设备：" + machineName + "上线");
        logger.info("设备ID:" + machineName + "  设备地址" + ctx.channel().remoteAddress() + "  上报的内容" + data);
    }

    //上报设备实时数据
    public void reportData(String data, ChannelHandlerContext ctx) {
        String channelId = ctx.channel().id().toString();
        //System.out.println(deviceGroup);
        //System.out.println(channelId);
        Device deviceNow = CacheUtil.deviceGroup.get(channelId);
       /* Collection<Device> deviceInfos = CacheUtil.deviceGroup.values();
        Device deviceNow = new Device();
        for (Device device : deviceInfos) {
            if (device.getChannelId() == ctx.channel().id().toString()) {
                deviceNow = device;
            }
        }*/
        MachineEntity machineEntity = machineService.getOne(new QueryWrapper<MachineEntity>().eq("MachineName", deviceNow.getMachineName()));
        List<DatatemplateEntity> list = datatemplateService.list(new QueryWrapper<DatatemplateEntity>().eq("TemplateID", machineEntity.getTemplateid()));
        //将上传的数据进行解析
        String[] strings = parseData(data, machineEntity, list);
        //将数据写到数据库中
        dataToBase(strings, machineEntity);
        // parseDataToBase(data, deviceNow.getMachineName());
        logger.info("设备ID:" + deviceNow.getMachineName() + "   设备地址" + ctx.channel().remoteAddress() + "  上报的内容" + data);


        //将实时数据存储在map中，为报警存储
        HashMap<String, String> map = new HashMap<>();
        int k = 0;
        for (DatatemplateEntity entity : list) {
            map.put(entity.getId().toString(), strings[k++]);
        }
        //报警信息处理
        //asynService.alarmProcess(machineEntity, map);
        alarmProcess(machineEntity, map);
    }

    //存储socket信息
    public void cacheSocket(String data, ChannelHandlerContext ctx) {
        //获取数据长度
        String substring = data.substring(10, 12);
        String datalengthStr = ConversionUtil.unsignedHexToDec(substring);
        Integer datalength = Integer.valueOf(datalengthStr);

        //获取数据
        String socketData = data.substring(12, 12 + datalength * 2);

        //解析socket数据
        String socketString = ConversionUtil.hexToString(socketData);

        SocketChannel channel = (SocketChannel) ctx.channel();
        String channelId = channel.id().toString();
        String[] strings = socketString.split(",");
        SocketVo socketVo = new SocketVo();

        socketVo.setAggrement(strings[0]);
        socketVo.setIp(strings[1]);
        socketVo.setPort(strings[2]);

        socketGroup.put(channelId, socketVo);

        String machineName = getNamebyId(channelId);

        logger.info(machineName + "  设备地址" + ctx.channel().remoteAddress() + "  上报的内容" + data);
    }

    //存储apn信息
    public void cacheApn(String data, ChannelHandlerContext ctx) {
        //获取数据长度
        String substring = data.substring(10, 12);
        String datalengthStr = ConversionUtil.unsignedHexToDec(substring);
        Integer datalength = Integer.valueOf(datalengthStr);

        //获取数据
        String apnData = data.substring(12, 12 + datalength * 2);

        //解析socket数据
        String apnString = ConversionUtil.hexToString(apnData);

        SocketChannel channel = (SocketChannel) ctx.channel();
        String channelId = channel.id().toString();
        ApnVo apnVo = new ApnVo();
        if (apnString.startsWith(",")) {
            apnVo.setCode("");
        } else {
            String data1 = apnString.substring(0, apnString.indexOf(","));
            apnVo.setCode(data1);
        }
        //获取第二个字符
        String s2 = apnString.substring(apnString.indexOf(",") + 1, apnString.length());

        if (substring.startsWith(",")) {
            apnVo.setCode("");
        } else {
            String data2 = s2.substring(0, apnString.indexOf(","));
            apnVo.setUsername(data2);
        }
        //获取第三个字符
        if (apnString.endsWith(",")) {
            apnVo.setPassword("");
        } else {
            apnVo.setPassword(apnString.substring(apnString.lastIndexOf(",") + 1, apnString.length()));
        }

        apnGroup.put(channelId, apnVo);
        String machineName = getNamebyId(channelId);

        logger.info(machineName + "  设备地址" + ctx.channel().remoteAddress() + "  上报的内容" + data);
    }

    //解析数据
    public String[] parseData(String data, MachineEntity machineEntity, List<DatatemplateEntity> list) {
        //获取数据长度
        String substring = data.substring(10, 12);
        String datalengthStr = ConversionUtil.unsignedHexToDec(substring);
        Integer datalength = Integer.valueOf(datalengthStr);
        //构建字符串存储从下位机传输过来的数据(裁剪)
        String[] strings = new String[datalength / 2];
        int j = 0;
        for (int i = 12; i < 12 + datalength * 2; ) {
            strings[j] = data.substring(i, i + 4);
            j++;
            i += 4;
        }

        //通过数据模板以及裁剪好的数据解析
        String[] realDataStr = parseData(list, strings);
        return realDataStr;
    }

    //通过数据模板对拆出来的数据解析
    public String[] parseData(List<DatatemplateEntity> list, String[] strings) {
        String[] dataStr = new String[list.size()];
        int datalength = strings.length;
        int i = 0;
        int j = 0;
        for (DatatemplateEntity entity : list) {
            String sort = entity.getSrot();
            if (entity.getRegisternum().equals("1") && j < datalength) {
                long datatypeid = entity.getDatatypeid();
                switch (String.valueOf(datatypeid)) {
                    case "1":
                        dataStr[i] = ConversionUtil.HexToBoolean(strings[j], sort);
                        break;
                    case "2":
                        dataStr[i] = ConversionUtil.unsignedHexToDec(strings[j], sort);
                        break;
                    case "3":
                        dataStr[i] = ConversionUtil.unsignedHexToDec10(strings[j], sort);
                        break;
                    case "4":
                        dataStr[i] = ConversionUtil.unsignedHexToDec100(strings[j], sort);
                        break;
                    case "5":
                        dataStr[i] = ConversionUtil.signedHexToDec(strings[j], sort);
                        break;
                    case "6":
                        dataStr[i] = ConversionUtil.signedHexToDec10(strings[j], sort);
                        break;
                    case "7":
                        dataStr[i] = ConversionUtil.signedHexToDec100(strings[j], sort);
                        break;
                    case "11":
                        dataStr[i] = ConversionUtil.hexToString(strings[j], sort);
                        break;
                }
            } else if (entity.getRegisternum().equals("2") && j < datalength) {
                long datatypeid = entity.getDatatypeid();
                switch (String.valueOf(datatypeid)) {
                    case "8":
                        dataStr[i] = ConversionUtil.unsignedHex32ToDec(strings[j] + strings[++j], sort);
                        break;
                    case "9":
                        dataStr[i] = ConversionUtil.signedHex32ToDec(strings[j] + strings[++j], sort);
                        break;
                    case "10":
                        dataStr[i] = ConversionUtil.hexToFloat(strings[j] + strings[++j], sort);
                        break;
                    case "11":
                        dataStr[i] = ConversionUtil.hexToString(strings[j] + strings[++j], sort);
                        break;
                }
            }
            i++;
            j++;
        }
        return dataStr;
    }

    //根据数据模板解析数据到数据库中(实时数据表以及历史数据表)
    public void dataToBase(String[] realDataStr, MachineEntity machineEntity) {
        //通过上面的过程我们已经成功将数据解析为字符串了。现在我们需要将其写入数据库中
        List<ControlrealtimeEntity> list1 = controlrealtimeService.list(new QueryWrapper<ControlrealtimeEntity>().eq("MachineId", machineEntity.getId()));
        //System.out.println(list1);
        List<HistroydataEntity> historydataList = new ArrayList<>();
        int i = 0;
        String time = DateUnit.dateFormat(new Date());
        for (ControlrealtimeEntity entity : list1) {
            String data = realDataStr[i];
            if (data == null) {
                data = "null";
            }
            entity.setRealtimevalue(data);
            entity.setOntime(time);
            HistroydataEntity histroydata = new HistroydataEntity();
            histroydata.setMachineid(entity.getMachineid());
            histroydata.setDatatemplateid(entity.getDatatemplateid());
            histroydata.setDatavalue(entity.getRealtimevalue());
            histroydata.setCreatetime(entity.getOntime());
            histroydata.setId(SnowFlakeUtil.getId());
            historydataList.add(histroydata);
            i++;

        }
        //将更新好的数据写回实时数据表
        controlrealtimeService.updateBatchById(list1);

        //将上传的数据写到历史数据表中
        histroydataService.saveHistorydataBatch(historydataList);
    }

    //报警信息处理
    public void alarmProcess(MachineEntity machineEntity, HashMap<String, String> map) {
        //将数据与监控登记点的数据进行比较
        List<AlarmregisterEntity> entities = alarmregisterService.list(new QueryWrapper<AlarmregisterEntity>().eq("MachineId", machineEntity.getId()));
        if (entities == null) {
            return;
        }
        for (AlarmregisterEntity entity : entities) {
            boolean flag = false;
            String realtimeValue = map.get(entity.getDatatemplateid().toString());
            //获取到实时数据后完成对比的功能
            //如果只有一个条件的话
            if (StringUtils.isEmpty(entity.getAndor())) {
                flag = compare(entity.getCondition1(), entity.getValue1(), realtimeValue);
            }
            //如果有两个条件而且第二个条件为与
            else if (entity.getAndor().equals("1")) {
                boolean b1 = compare(entity.getCondition1(), entity.getValue1(), realtimeValue);
                boolean b2 = compare(entity.getCondition2(), entity.getValue2(), realtimeValue);
                flag = b1 && b2;
            }
            //如果有两个条件而且第二个条件为或
            else if (entity.getAndor().equals("0")) {
                boolean b1 = compare(entity.getCondition1(), entity.getValue1(), realtimeValue);
                boolean b2 = compare(entity.getCondition2(), entity.getValue2(), realtimeValue);
                flag = b1 || b2;
            }

            if (flag) {
                AlarmhisdataEntity alarmhisdataEntity = new AlarmhisdataEntity();
                BeanUtils.copyProperties(entity, alarmhisdataEntity);
                alarmhisdataEntity.setDatavalue(map.get(entity.getDatatemplateid().toString()));
                alarmhisdataEntity.setCreatetime(DateUnit.dateFormat(new Date()));
                alarmhisdataService.save(alarmhisdataEntity);

                if (entity.getIsonwarning().equals("0")) {
                    MachinekindEntity machinekindEntity = machinekindService.getById(machineEntity.getMachinekind());
                    String[] options = entity.getIssendmessage().split(",");
                    for (String option : options) {
                        switch (option) {
                            case "1": {
                                //获取到需要发送信息的邮箱
                                List<String> emails = machineService.getEmail(machineEntity.getMachinename());
                                //获取到需要发送的提示信息
                                String content = "设备型号：" + machinekindEntity.getMachinenumber() + "，设备名称：" + machinekindEntity.getMachinename() + "，设备Id:" + machineEntity.getMachinename() + "，报警内容：" + entity.getAlarmcontent() + "，异常值为：" + realtimeValue;
                                //循环发送信息
                                for (String email : emails) {
                                    try {
                                        alarmregisterService.sendEmail(email, content);
                                    } catch (Exception e) {
                                        e.printStackTrace();
                                    }
                                }
                                break;
                            }
                            case "2": {
                                //获取到需要发送信息的手机号码
                                List<String> phones = machineService.getPhone(machineEntity.getMachinename());
                                //获取到需要发送的提示信息
                                String content = entity.getAlarmcontent() + ",异常值为：" + realtimeValue;

                                //循环发送信息
                                for (String phone : phones) {
                                    try {
                                        alarmregisterService.sendMessage(phone, machinekindEntity.getMachinenumber(), machinekindEntity.getMachinename(), machineEntity.getMachinename(), content);
                                    } catch (Exception e) {
                                        e.printStackTrace();
                                    }
                                }
                                break;
                            }
                            case "3": {
                                System.out.println("发送强技通");
                                break;
                            }

                            case "4": {
                                System.out.println("发送微信");
                                break;
                            }

                            case "5": {
                                System.out.println("其他平台");
                                break;
                            }
                        }
                    }
                    entity.setIsonwarning("1");
                    alarmregisterService.updateById(entity);
                }
            } else {
                if (entity.getIsonwarning().equals("1")) {
                    entity.setIsonwarning("0");
                    alarmregisterService.updateById(entity);
                }
            }
        }
    }

    /**
     * @param condition1    条件
     * @param value         条件值
     * @param realtimeValue 实时数据值
     * @return
     */
    public boolean compare(String condition1, String value, String realtimeValue) {
        //定义flag判断
        boolean flag = false;
        //条件值
        Float f1 = Float.valueOf(realtimeValue);
        //实时数据的值
        Float f2 = Float.valueOf(value);
        switch (condition1) {
            case "1":
                flag = (f1 == f2);
                break;
            case "2":
                flag = (f1 != f2);
                break;
            case "3":
                flag = f1 > f2;
                break;
            case "4":
                flag = f1 >= f2;
                break;
            case "5":
                flag = f1 < f2;
                break;
            case "6":
                flag = f1 <= f2;
                break;
        }
        return flag;
    }

    //验证成功在设备组中添加设备的信息
    public void addMachineToGroup(ChannelHandlerContext ctx, String machineName) {
        Collection<Device> deviceInfos = CacheUtil.deviceGroup.values();
        for (Device device : deviceInfos) {
            if (device.getMachineName().equals(machineName)) {
                String channelId = device.getChannelId();
                Channel channel = cacheClientChannel.get(channelId);
                channel.close();
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }

        SocketChannel channel = (SocketChannel) ctx.channel();
        String channelId = channel.id().toString();
        //构建设备信息｛下位机、中继器、IO板卡｝
        Device device = new Device();
        device.setChannelId(channelId);
        device.setNumber(UUID.randomUUID().toString());
        device.setIp(channel.remoteAddress().getHostString());
        device.setPort(channel.remoteAddress().getPort());
        device.setConnectTime(new Date());
        device.setMachineName(machineName);
        //添加设备信息
        deviceGroup.put(channelId, device);
        //System.out.println(deviceGroup);
        CacheUtil.cacheClientChannel.put(channelId, channel);
    }

    //根据管道的ID获取到设备的名称
    private String getNamebyId(String channelId) {
        Collection<Device> deviceInfos = CacheUtil.deviceGroup.values();
        Device deviceEntity = null;
        for (Device device : deviceInfos) {
            if (device.getChannelId().equals(channelId)) {
                deviceEntity = device;
            }
        }
        if (deviceEntity != null) {
            return deviceEntity.getMachineName();
        } else {
            return null;
        }
    }

    @Override
    public String getVersion(String machineName) {
        Collection<Device> deviceInfos = CacheUtil.deviceGroup.values();
        Device deviceEntity = null;
        for (Device device : deviceInfos) {
            if (device.getMachineName().equals(machineName)) {
                deviceEntity = device;
                Channel channel = CacheUtil.cacheClientChannel.get(device.getChannelId());
                String message = "5b000000fc0200ff6b5d";
                System.out.println("下发数据获取版本号" + message);
                byte[] bytes = ConversionUtil.hexStringToByteArray(message);
                channel.writeAndFlush(Unpooled.copiedBuffer(bytes));
            }
        }

        if (deviceEntity == null) {
            return null;
        }

        String channelId = deviceEntity.getChannelId();
        String s = null;
        long start = System.currentTimeMillis();
        while (s == null) {
            long end = System.currentTimeMillis();
            try {
                Thread.sleep(250);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            if (end - start > 5000) {
                break;
            }
            s = CacheUtil.version.get(channelId);
            version.remove(channelId);
        }
        return s;
    }

    //暂存前端传输上来的文件
    @Override
    public void saveFile(MultipartFile newFile) throws IOException {
        if (binFile.size() > 0) {
            binFile.clear();
        }
        binFile.put("total", String.valueOf(newFile.getSize()));
        InputStream fis = newFile.getInputStream();
        //每251个字节封装为一个包
        //byte[] bys = new byte[251];
        int len = 0;
        int num = 0;
        int count = 0;
        StringBuilder sb1 = new StringBuilder();
        while ((len = fis.read()) != -1) {
            count++;
            String value = ConversionUtil.DecToHexOneByte(len);
            sb1.append(value);
            if (count == 251) {
                num++;
                binFile.put(String.valueOf(num), sb1.toString());
                sb1.delete(0, sb1.length());
                count = 0;
            }
        }
        //最后一个包不满251个字节的时候
        binFile.put(String.valueOf(++num), sb1.toString());
        binFile.put("package", String.valueOf(num));
        return;
    }

    //设备返回当前程序的版本号
    private void parseVersion(String data, ChannelHandlerContext ctx) {
        String versionHex = data.substring(12, 14);
        //将版本号的16进制转为十进制表示
        String s = ConversionUtil.unsignedHexToDec(versionHex);
        //十进制除以10为最终的表现形式
        Float value = Float.valueOf(s) / 10;
        //存储版本号信息
        ChannelId channelId = ctx.channel().id();
        version.put(channelId.toString(), value.toString());
    }

    //设备关于更新的回复
    private void parseStatus(String data, ChannelHandlerContext ctx) {
        InfoProtocol infoProtocol = new InfoProtocol();
        String message = "设备准备就绪";
        infoProtocol.setMsgObj(message);
        //转发消息到Ws
        CacheUtil.wsChannelGroup.writeAndFlush(MsgUtil.buildMsg(infoProtocol));
    }

    //服务器返回程序包的大小和程序包的总数
    private void responseSum(String data, ChannelHandlerContext ctx) {
        if (binFile.size() == 0) {
            return;
        }
        //获取程序包的大小
        String total = binFile.get("total");
        String hexTotal = Integer.toHexString(Integer.valueOf(total));
        hexTotal = StringUtils.leftPad(hexTotal, 8, "0");
        //获取程序报的总包数目
        String packages = binFile.get("package");
        String hexPackages = Integer.toHexString(Integer.valueOf(packages));
        hexPackages = StringUtils.leftPad(hexPackages, 8, "0");

        StringBuilder sb1 = new StringBuilder();

        sb1.append("000000fe08").append(hexTotal).append(hexPackages);
        String crc8 = CRC8Utils.CRC8_REMAXIM(sb1.toString());

        StringBuilder sb2 = new StringBuilder();
        sb2.append("5b").append(sb1).append(crc8).append("5d");

        byte[] bytes = ConversionUtil.hexStringToByteArray(sb2.toString());
        ctx.channel().writeAndFlush(Unpooled.copiedBuffer(bytes));
    }

    //发送具体的程序包给设备
    private void sendData(String data, ChannelHandlerContext ctx) {
        if (binFile.size() == 0) {
            return;
        }
        //获取总包数
        Float packageAll = Float.valueOf(binFile.get("package"));

        String packaheNum = data.substring(12, 20);
        //解析为十进制
        String s = ConversionUtil.unsignedHexToDec(packaheNum);
        //获取程序包数据
        String program = binFile.get(s);
        //拼接需要响应的结果
        StringBuilder sb1 = new StringBuilder();
        sb1.append(packaheNum).append(program);
        int lengthDec = sb1.toString().length();
        String lengthHex = ConversionUtil.DecToHexOneByte(lengthDec / 2);
        StringBuilder sb2 = new StringBuilder();
        sb2.append("000000ff").append(lengthHex).append(sb1);
        String crc8 = CRC8Utils.CRC8_REMAXIM(sb2.toString());
        StringBuilder sb3 = new StringBuilder();
        sb3.append("5b").append(sb2).append(crc8).append("5d");
        byte[] bytes = ConversionUtil.hexStringToByteArray(sb3.toString());
        ctx.channel().writeAndFlush(Unpooled.copiedBuffer(bytes));

        //当前正在发送的包数
        Float curpackage = Float.valueOf(s);
        //进度条数值
        int progress = (int) ((curpackage / packageAll) * 100);
        //转发消息到Ws
        CacheUtil.wsChannelGroup.writeAndFlush(new TextWebSocketFrame(String.valueOf(progress)));
        if (progress == 100) {
            String channelId = ctx.channel().id().toString();
            ctx.close();
            System.out.println("上传结束");
        }
    }

    //清除map中存储的bin文件
    @Override
    public void deleteBin() {
        if (binFile.size() > 0) {
            binFile.clear();
        }
    }

}
